/**
 * Copyright (C) 2025 pony working team
 * SPDX-License-Identifier: MulanPSL-2.0
 */

/* define to prevent recursive inclusion -------------------------------------*/
#ifndef __PONY_KAL_H__
#define __PONY_KAL_H__

/* includes (standard library, system) ---------------------------------------*/
#include <stdint.h>
#include <stddef.h>
/* includes (other library) --------------------------------------------------*/
/* includes (project) --------------------------------------------------------*/
#include <x_config.h>
#include <x_magic.h>
/* includes (local) ----------------------------------------------------------*/

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/* defines -------------------------------------------------------------------*/
/* typedefs ------------------------------------------------------------------*/

typedef x_magic_t k_task_t;
typedef x_magic_t k_mutex_t;
typedef x_magic_t k_sem_t;
typedef x_magic_t k_event_t;
typedef x_magic_t k_mq_t;
typedef x_magic_t k_timer_t;

/* macro ---------------------------------------------------------------------*/
/* inlines -------------------------------------------------------------------*/
/* externs -------------------------------------------------------------------*/

/* task */
extern int k_task_create(k_task_t *task, const char *name, uint8_t prio, size_t stack_size,
                         int (*entry)(uintptr_t arg), uintptr_t arg);
extern int k_task_delete(k_task_t *task);
extern int k_task_exit(void);
extern int k_task_resume(k_task_t *task);
extern int k_task_suspend(k_task_t *task);
extern void k_task_lock(void);
extern void k_task_unlock(void);
extern void k_task_msleep(uint32_t ms);
extern int k_task_prio_set(k_task_t *task, int prio);
extern int k_task_prio_get(k_task_t *task);
extern void k_task_stat(void);
extern int k_task_stack_space(k_task_t *task);

/* mutex */
extern int k_mutex_init(k_mutex_t *mutex);
extern int k_mutex_destroy(k_mutex_t *mutex);
extern int k_mutex_timedlock(k_mutex_t *mutex, uint32_t timeout);
extern int k_mutex_trylock(k_mutex_t *mutex);
extern int k_mutex_lock(k_mutex_t *mutex);
extern int k_mutex_unlock(k_mutex_t *mutex);

/* semaphore */
extern int k_sem_init(k_sem_t *sem, int limit, int value);
extern int k_sem_destroy(k_sem_t *sem);
extern int k_sem_timedwait(k_sem_t *sem, uint32_t timeout);
extern int k_sem_trywait(k_sem_t *sem);
extern int k_sem_wait(k_sem_t *sem);
extern int k_sem_post(k_sem_t *sem);

/* event */
#define K_EVENT_WAITMODE_AND 4 /* all bits must be set */
#define K_EVENT_WAITMODE_OR  2 /* any bit must be set  */
#define K_EVENT_WAITMODE_CLR 1 /* clear when satisfied */

extern int k_event_init(k_event_t *event);
extern int k_event_destroy(k_event_t *event);
extern int k_event_timedrecv(k_event_t *event, uint32_t wanted, uint32_t option, uint32_t timeout,
                             uint32_t *recved);
extern int k_event_tryrecv(k_event_t *event, uint32_t wanted, uint32_t option, uint32_t *recved);
extern int k_event_recv(k_event_t *event, uint32_t wanted, uint32_t option, uint32_t *recved);
extern int k_event_send(k_event_t *event, uint32_t value);
extern int k_event_clear(k_event_t *event, uint32_t value);

/* message queue */
typedef struct k_mq_buf {
    uint8_t *buf;
    size_t len;
} k_mq_buf_t;

extern int k_mq_create(k_mq_t *mq, const char *name, size_t msg_size, size_t max_msgs,
                       uint32_t options);
extern int k_mq_delete(k_mq_t *mq);
extern int k_mq_timedsend(k_mq_t *mq, const void *buf, size_t len, uint32_t timeout);
extern int k_mq_trysend(k_mq_t *mq, const void *buf, size_t len);
extern int k_mq_send(k_mq_t *mq, const void *buf, size_t len);
extern int k_mq_timedrecv(k_mq_t *mq, void *buf, size_t len, uint32_t timeout);
extern int k_mq_tryrecv(k_mq_t *mq, void *buf, size_t len);
extern int k_mq_recv(k_mq_t *mq, void *buf, size_t len);

/* software timer */
#define K_TIMER_MODE_ONESHOT  0
#define K_TIMER_MODE_REPEATED 1

extern int k_timer_create(k_timer_t *timer, uint32_t interval, uint16_t mode,
                          void (*pfn)(uintptr_t arg), uintptr_t arg);
extern int k_timer_delete(k_timer_t *timer);
extern int k_timer_start(k_timer_t *timer);
extern int k_timer_stop(k_timer_t *timer);

/* time */
extern uint64_t k_mseconds(void);
extern uint32_t k_tick2ms(uint32_t ticks);
extern uint32_t k_ms2tick(uint32_t ms);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* __PONY_KAL_H__ */
